/**
 * \file  antiviral_set.h
 * \brief Definition of AntiviralSet class.
 *
 * ASO: Antiviral Sequence Optimizer
 * <http://aso.googlecode.com/>
 * Copyright (C) 2010 Velez Ezequiel, Peralta Andres, FuDePAN
 *
 * This file is part of the ASO project.
 *
 * Contents:       Header file for ASO providing class AntiviralSet.
 *
 * System:         ASO
 * Language:       C++
 *
 * Author:         Velez Ezequiel, Peralta Andres
 * E-Mail:
 *
 * ASO is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ASO is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ASO.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef ANTIVIRAL_SET_H
#define ANTIVIRAL_SET_H

#include <mili/mili.h>
#include "aso-core/antiviral_imp.h"

typedef std::set<const ResisBasedAntiviral*> Avs;

struct AntiviralSet
{
    /*! Redefinicion uns a lista de antivirales a Antiviral Set. */
    Avs antivirals;

    /*! Operador de Equivalencia */
    inline bool operator==(const AntiviralSet& other) const
    {
        return antivirals == other.antivirals;
    }

    /*! Agrega un antiviral al conjunto */
    void add_antiviral(const ResisBasedAntiviral& antiviral);

    /*! Funcion para obtener un conjunto de secuencias producto de aplicar este antiviral a la secuencia dada */
    void observe_mutants(const biopp::PseudoNucSequence& sequence, MutantDist& mutant_list);

    /*! Combina un conjunto de antivirales. */
    void combine_set(ResisBasedAntiviral& combined);

    /*! Imprime los nombres de los antivirales que contiene */
    void get_info(std::string& out) const;

};

/*! Filtra el conjunto de antivirales de acuerdo a un atributo */
template<class T>
bool filter(const Avs& in, const std::string& condName, const T& condValue, Avs& out)
{
    bool success(false);
    mili::CAutonomousIterator<Avs> it(in);
    while (!it.end())
    {
        T aux;
        if ((*it)->get_attrib(condName, aux))       //! si contiene el atributo
        {
            if (aux == condValue)                   //! si concuerda el valor
            {
                mili::insert_into(out, *it);
                success = true;
            }
        }
        ++it;
    }
    return success;
}

/*! Filtra el conjunto de antivirales de acuerdo a un conjunto de atributos */
void filter_by_group(const Avs& in, const AttribSet& terms, Avs& out);

/*! Iterador del Conjunto de Antivirales */
typedef mili::CAutonomousIterator<Avs> AVIterator;

#endif
